//
//  RZIMUtility.m
//  RZIM
//
//  Created by reyzhang on 2021/8/3.
//

#import "RZKitUtility.h"
#import "RZIMConfig.h"
#import "pinyin.h"
#import "RZUserInfo.h"
#import "RZMessageInfo.h"
//#import "VoiceConverter.h"
#import <Photos/Photos.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import "LameTool.h"



@implementation RZKitUtility


/*!
 会话列表会话时间转换

 @return        可视化的时间字符串

 @discussion 如果该时间是今天的，则返回值为"HH:mm"格式的字符串；
 如果该时间是昨天的，则返回字符串资源中Yesterday对应语言的字符串；
 如果该时间是昨天之前或者今天之后的，则返回"yyyy-MM-dd"的字符串。
 */
+ (NSString *)convertConversationTime:(NSString *)timeStr {
    NSString *timeText = nil;
    NSDateFormatter *formatter = [self getDateFormatter];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *messageDate = [formatter dateFromString:timeStr];
    if ([self isSameYear:messageDate]) {
        if ([self isSameMonth:messageDate]) {
            NSInteger intervalDays = [self getIntervalDays:messageDate];
            if (intervalDays == 0) {
                NSString *formatStr = [self getDateFormatterString:messageDate];
                [formatter setDateFormat:formatStr];
                return timeText = [formatter stringFromDate:messageDate];
            } else if (intervalDays == 1) {
                return timeText = @"昨天";
            } else if (intervalDays < 7) {
                [formatter setDateFormat:@"eeee"];
                return timeText = [formatter stringFromDate:messageDate];
            } else {
                [formatter setDateFormat:RZIMConfigCenter.ui.globalConversationDateFormate];
                return timeText = [formatter stringFromDate:messageDate];
            }
        } else {
            [formatter setDateFormat:RZIMConfigCenter.ui.globalConversationDateFormate];
            return timeText = [formatter stringFromDate:messageDate];
        }
    }
    [formatter setDateFormat:RZIMConfigCenter.ui.globalConversationDateFormate];
    return timeText = [formatter stringFromDate:messageDate];
}

+ (NSDateFormatter *)getDateFormatter {
    static NSDateFormatter *dateFormatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dateFormatter = [[NSDateFormatter alloc] init];
    });
    return dateFormatter;
}

+ (BOOL)isSameYear:(NSDate *)messageDate{
    NSDate *now = [NSDate date];
    NSDateFormatter *formatter = [self getDateFormatter];
    [formatter setDateFormat:@"yyyy"];
    NSInteger currentYear = [[formatter stringFromDate:now] integerValue];
    NSInteger msgYear = [[formatter stringFromDate:messageDate] integerValue];
    if (currentYear == msgYear) {
        return YES;
    }
    return NO;
}

+ (BOOL)isSameMonth:(NSDate *)messageDate{
    NSDate *now = [NSDate date];
    NSDateFormatter *formatter = [self getDateFormatter];
    [formatter setDateFormat:@"MM"];
    NSInteger currentMonth = [[formatter stringFromDate:now] integerValue];
    NSInteger msgMonth = [[formatter stringFromDate:messageDate] integerValue];
    if (currentMonth == msgMonth) {
        return YES;
    }
    return NO;
}

+ (NSInteger)getIntervalDays:(NSDate *)messageDate{
    NSDate *now = [NSDate date];
    NSDateFormatter *formatter = [self getDateFormatter];
    [formatter setDateFormat:@"dd"];
    NSInteger currentDay = [[formatter stringFromDate:now] integerValue];
    NSInteger msgDay = [[formatter stringFromDate:messageDate] integerValue];
    return currentDay - msgDay;
}


+ (NSString *)getDateFormatterString:(NSDate *)messageDate {
    NSString *formatStringForHours =
        [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]];
    NSRange containsA = [formatStringForHours rangeOfString:@"a"];
    BOOL hasAMPM = containsA.location != NSNotFound;
    NSString *formatStr = nil;
    if (hasAMPM) {
        formatStr = [self getFormatStringByMessageDate:messageDate];
    } else {
        formatStr = @"HH:mm";
    }
    return formatStr;
}

+ (NSString *)getFormatStringByMessageDate:(NSDate *)messageDate {
    NSString *formatStr = nil;
    if ([[self class] isBetweenFromHour:0 toHour:6 currentDate:messageDate]) {
        formatStr = @"h:mm a";
    } else if ([[self class] isBetweenFromHour:6 toHour:12 currentDate:messageDate]) {
        formatStr = @"h:mm a";
    } else if ([[self class] isBetweenFromHour:12 toHour:13 currentDate:messageDate]) {
        formatStr = @"h:mm a";
    } else if ([[self class] isBetweenFromHour:13 toHour:18 currentDate:messageDate]) {
        formatStr = @"h:mm a";
    } else {
        formatStr = @"h:mm a";
    }
    return formatStr;
}

+ (BOOL)isBetweenFromHour:(NSInteger)fromHour toHour:(NSInteger)toHour currentDate:(NSDate *)currentDate {
    NSDate *date1 = [self getCustomDateWithHour:fromHour currentDate:currentDate];
    NSDate *date2 = [self getCustomDateWithHour:toHour currentDate:currentDate];
    if (([currentDate compare:date1] == NSOrderedDescending || [currentDate compare:date1] == NSOrderedSame) &&
        ([currentDate compare:date2] == NSOrderedAscending))
        return YES;
    return NO;
}

+ (NSDate *)getCustomDateWithHour:(NSInteger)hour currentDate:(NSDate *)currentDate {
    NSCalendar *currentCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSDateComponents *currentComps;
    NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday |
                          NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    currentComps = [currentCalendar components:unitFlags fromDate:currentDate];
    //设置当天的某个点
    NSDateComponents *resultComps = [[NSDateComponents alloc] init];
    [resultComps setYear:[currentComps year]];
    [resultComps setMonth:[currentComps month]];
    [resultComps setDay:[currentComps day]];
    [resultComps setHour:hour];
    NSCalendar *resultCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    return [resultCalendar dateFromComponents:resultComps];
}


/*!
 聊天页面消息时间转换

 @return        可视化的时间字符串

 @discussion 如果该时间是今天的，则返回值为"HH:mm"格式的字符串；
 如果该时间是昨天的，则返回"Yesterday HH:mm"的字符串（其中，Yesterday为字符串资源中Yesterday对应语言的字符串）；
 如果该时间是昨天之前或者今天之后的，则返回"yyyy-MM-dd HH:mm"的字符串。
 */
+ (NSString *)convertMessageTime:(NSString *)timeStr {
    return nil;
}


+ (UIImage *)imageNamed:(NSString *)name ofBundle:(NSString *)bundleName {
//    NSString *keyString = [NSString stringWithFormat:@"%@%@", bundleName, name];
    UIImage *image = nil;
    //method1:
//    {
//        NSBundle *bundle = [NSBundle bundleForClass:[self class]];
//        NSString *image_path = [bundle pathForResource:name ofType:@"png" inDirectory:bundleName];
//        image = [UIImage imageWithContentsOfFile:image_path];
//    }

    //method2:
//    {
//        NSString *image_name = name;
//        if (![image_name hasSuffix:@".png"]) {
//            image_name = [NSString stringWithFormat:@"%@.png", name];
//        }
//        NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
//        NSString *bundlePath = [resourcePath stringByAppendingPathComponent:bundleName];
//        NSString *image_path = [bundlePath stringByAppendingPathComponent:image_name];
//        image = [UIImage imageWithContentsOfFile:image_path];
//    }
    
    //method3
    NSString *fileName = [NSString stringWithFormat:@"%@/%@",bundleName,name];
    image = [UIImage imageNamed:fileName];

    return image;
}

+ (UIImage *)imageWithColor:(UIColor *)color {
    return [self imageWithColor:color size:CGSizeMake(1, 1)];
}

+ (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size {
    if (!color || size.width <= 0 || size.height <= 0) return nil;
    CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}



/**
 *  汉字转拼音
 *
 *  @param hanZi 汉字
 *
 *  @return 转换后的拼音
 */
+ (NSString *)hanZiToPinYinWithString:(NSString *)hanZi {
    if (!hanZi) {
        return nil;
    }
    NSString *pinYinResult = [NSString string];
    for (int j = 0; j < hanZi.length; j++) {
        NSString *singlePinyinLetter = nil;
        if ([self isChinese:[hanZi substringWithRange:NSMakeRange(j, 1)]]) {
            singlePinyinLetter =
                [[NSString stringWithFormat:@"%c", pinyinFirstLetter([hanZi characterAtIndex:j])] uppercaseString];
        } else {
            singlePinyinLetter = [hanZi substringWithRange:NSMakeRange(j, 1)];
        }

        pinYinResult = [pinYinResult stringByAppendingString:singlePinyinLetter];
    }
    return pinYinResult;
}

+ (BOOL)isChinese:(NSString *)text {
    NSString *match = @"(^[\u4e00-\u9fa5]+$)";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match];
    return [predicate evaluateWithObject:text];
}

+ (NSString *)getFirstUpperLetter:(NSString *)hanzi {
    NSString *pinyin = [self hanZiToPinYinWithString:hanzi];
    NSString *firstUpperLetter = [[pinyin substringToIndex:1] uppercaseString];
    if ([firstUpperLetter compare:@"A"] != NSOrderedAscending &&
        [firstUpperLetter compare:@"Z"] != NSOrderedDescending) {
        return firstUpperLetter;
    } else {
        return @"#";
    }
}

+ (NSMutableDictionary *)sortedArrayWithPinYinDic:(NSArray *)userList {
    NSArray *users = [userList mutableCopy];
    if (!users)
        return nil;
    NSArray *_keys = @[
        @"A",
        @"B",
        @"C",
        @"D",
        @"E",
        @"F",
        @"G",
        @"H",
        @"I",
        @"J",
        @"K",
        @"L",
        @"M",
        @"N",
        @"O",
        @"P",
        @"Q",
        @"R",
        @"S",
        @"T",
        @"U",
        @"V",
        @"W",
        @"X",
        @"Y",
        @"Z",
        @"#"
    ];

    NSMutableDictionary *infoDic = [NSMutableDictionary new];
    NSMutableArray *_tempOtherArr = [NSMutableArray new];
    BOOL isReturn = NO;

    for (NSString *key in _keys) {

        if ([_tempOtherArr count]) {
            isReturn = YES;
        }
        NSMutableArray *tempArr = [NSMutableArray new];
        for (id user in users) {
            NSString *firstLetter;

            if ([user isMemberOfClass:[RZUserInfo class]]) {
                RZUserInfo *userInfo = (RZUserInfo *)user;
                firstLetter = [self getFirstUpperLetter:userInfo.username];
            }
            

            if ([firstLetter isEqualToString:key]) {
                [tempArr addObject:user];
            }

            if (isReturn)
                continue;
            char c = [firstLetter characterAtIndex:0];
            if (isalpha(c) == 0) {
                [_tempOtherArr addObject:user];
            }
        }
        if (![tempArr count])
            continue;
        [infoDic setObject:tempArr forKey:key];
    }
    if ([_tempOtherArr count])
        [infoDic setObject:_tempOtherArr forKey:@"#"];

    NSArray *keys = [[infoDic allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {

        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    NSMutableArray *allKeys = [[NSMutableArray alloc] initWithArray:keys];

    NSMutableDictionary *resultDic = [NSMutableDictionary new];
    [resultDic setObject:infoDic forKey:@"infoDic"];
    [resultDic setObject:allKeys forKey:@"allKeys"];
    return resultDic;
}

+ (BOOL)isContains:(NSString *)firstString withString:(NSString *)secondString {
    if (firstString.length == 0 || secondString.length == 0) {
        return NO;
    }
    NSString *twoStr = [[secondString stringByReplacingOccurrencesOfString:@" " withString:@""] lowercaseString];
    if ([[firstString lowercaseString] containsString:[secondString lowercaseString]] ||
        [[firstString lowercaseString] containsString:twoStr] ||
        [[[self hanZiToPinYinWithString:firstString] lowercaseString] containsString:twoStr]) {
        return YES;
    }
    return NO;
}


+ (BOOL)isHairHead {
    if (@available(iOS 11.0, *)) {
        UIEdgeInsets safeAreaInsets = [UIApplication sharedApplication].delegate.window.safeAreaInsets;
        if (UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) {
            return safeAreaInsets.left > 0.0f;
        }else {
            return safeAreaInsets.bottom > 0.f;
        }
    }
    return NO;
}


+ (UIEdgeInsets)getWindowSafeAreaInsets {
    UIEdgeInsets result = UIEdgeInsetsZero;
    if (@available(iOS 11.0, *)) {
        UIWindow *window = [self getKeyWindow];
        if (window) {
            result = window.safeAreaInsets;
        }
    }else{
        result.top = [[UIApplication sharedApplication] statusBarFrame].size.height;
    }
    return result;
}


+ (UIWindow *)getKeyWindow {
    UIWindow *keyWindow;
    for (UIWindow *window in [UIApplication sharedApplication].windows) {
        if ([window isKeyWindow]) {
            keyWindow = window;
            break;
        }
    }
    return keyWindow;
}

+ (CGSize)getTextDrawingSize:(NSString *)text font:(UIFont *)font constrainedSize:(CGSize)constrainedSize {
    if (text.length <= 0) {
        return CGSizeZero;
    }

    if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
        NSDictionary *attributes = @{NSFontAttributeName : font, NSParagraphStyleAttributeName : paragraphStyle};

        return [text boundingRectWithSize:constrainedSize
                                  options:(NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
                               attributes:attributes
                                  context:nil].size;
    }
    return CGSizeZero;
}


/**
 获取北京时间 13位的时间戳
 */
+ (NSString *)get13TimeStemp{
    
    //先将当前时间转成东8时区 时间
    NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];//获取当前时间0秒后的时间
    NSDateFormatter *formater = [[NSDateFormatter alloc] init];
    [formater setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSTimeZone *timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT+0800"];
    [formater setTimeZone:timeZone]; // 指定东8区
    NSString *dateStr = [formater stringFromDate:date];
    
    //再将转换后的时间字符串， 转成日期
    NSDate *beijingDate = [formater dateFromString:dateStr];
    NSTimeInterval time=[beijingDate timeIntervalSince1970]*1000;// *1000 是精确到毫秒，不乘就是精确到秒
    NSString *timeString = [NSString stringWithFormat:@"%.0f", time];
    return timeString;
}


+ (BOOL)convertAMR:(NSString *)amrFilePath
             toWAV:(NSString *)wavFilePath
{
    BOOL ret = NO;
    BOOL isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:amrFilePath];
    if (isFileExists) {
//        [VoiceConverter amrToWav:amrFilePath wavSavePath:wavFilePath];
        ret = isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:wavFilePath];
        
    }
    
    return ret;
}

+ (BOOL)convertWAV:(NSString *)wavFilePath
             toAMR:(NSString *)amrFilePath {
    BOOL ret = NO;
    BOOL isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:wavFilePath];
    if (isFileExists) {
//        [VoiceConverter wavToAmr:wavFilePath amrSavePath:amrFilePath];
        ret = isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:amrFilePath];
    }
    
    return ret;
}


/**
 wav to mp3
 */
+ (BOOL)convertWAV:(NSString *)wavFilePath
             toMP3:(NSString *)mp3FilePath {
    BOOL ret = NO;
    BOOL isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:wavFilePath];
    if (isFileExists) {
        mp3FilePath = [LameTool audioToMP3:wavFilePath isDeleteSourchFile:NO];
        ret = isFileExists = [[NSFileManager defaultManager] fileExistsAtPath:mp3FilePath];
    }
    
    return ret;
}


//判断文件是否已经在沙盒中存在
+ (BOOL)isFileExist:(NSString *)fileName
{
    return [self isFileExist:fileName needDel:NO];
}


//判断文件是否已经在沙盒中存在
+ (BOOL)isFileExist:(NSString *)fileName needDel:(BOOL)needDel
{
    //document 沙盒
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
    NSString *filePath = [path stringByAppendingPathComponent:fileName];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL result = [fileManager fileExistsAtPath:filePath];
    
    //如果找到，并且允许删除
    if (result && needDel) {
        [fileManager removeItemAtPath:filePath error:nil];
    }
    return result;
}




/**
 显示AlertController
 */
+ (void)showAlertWithTitle:(NSString *)title
                   message:(NSString *)message
                      from:(UIViewController *)vc
                showCancel:(BOOL)showCancel
                   confirmHandler:(void(^)(void))block {
    
    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *confirm = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        !block ?: block();
    }];
    
    if (showCancel) {
        UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        [alertVC addAction:cancel];
    }
    [alertVC addAction:confirm];
    [vc presentViewController:alertVC animated:YES completion:nil];
    
    
}


/**
 根据文件束，获取本地资源 url
 */
+ (void)getURlByAsset:(id)asset success:(void (^)(NSURL *))success
{
    if ([asset isKindOfClass:[PHAsset class]]) {
        PHVideoRequestOptions* options = [[PHVideoRequestOptions alloc] init];
        options.version = PHVideoRequestOptionsVersionOriginal;
        options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
        options.networkAccessAllowed = YES;
        [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset* avasset, AVAudioMix* audioMix, NSDictionary* info){
            AVURLAsset *videoAsset = (AVURLAsset*)avasset;
            // NSLog(@"AVAsset URL: %@",myAsset.URL);
            !success ?: success(videoAsset.URL);
        }];
    } else if ([asset isKindOfClass:[ALAsset class]]) {
        NSURL *videoURL = [asset valueForProperty:ALAssetPropertyAssetURL]; // ALAssetPropertyURLs
        !success ?: success(videoURL);
    }
}


/*!
 对原有视频进行压缩
 */
+ (void)videoPressWithOrginUrl:(NSURL *)videoUrl success:(void (^)(NSURL *))success {
    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL: videoUrl options:nil];
    NSDateFormatter* formater = [[NSDateFormatter alloc] init];
    [formater setDateFormat:@"yyyyMMddHHmmss"];
    NSString *fileName = [NSString stringWithFormat:@"output-%@.mp4",[formater stringFromDate:[NSDate date]]];
    NSString *outfilePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/%@", fileName];
    NSLog(@"前--视频文件outPath = %@  视频文件size = %.2f M",outfilePath,[self fileSizeAtPath:videoUrl.path]); // 本地文件
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
    if ([compatiblePresets containsObject: AVAssetExportPresetMediumQuality])//AVAssetExportPresetMediumQuality
    {
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality];
        exportSession.outputURL = [NSURL fileURLWithPath:outfilePath];
        //           exportSession.outputFileType = AVFileTypeMPEG4;
        exportSession.outputFileType = AVFileTypeQuickTimeMovie;
        exportSession.shouldOptimizeForNetworkUse = YES;
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            if ([exportSession status] == AVAssetExportSessionStatusCompleted) {
                NSLog(@"AVAssetExportSessionStatusCompleted---转换成功");
                NSLog(@"后--视频文件outPath = %@  视频文件size = %.2f M",outfilePath,[self fileSizeAtPath:outfilePath]); // 本地文件
                
                NSURL *filePathURL = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@",outfilePath]];
                !success ?: success(filePathURL);
            }else if ([exportSession status] == AVAssetExportSessionStatusFailed) {
                !success ?: success(nil);
            }
        }];
    }else {
        !success ?: success(videoUrl);
    }
}

+ (float)fileSizeAtPath:(NSString*) filePath
{
    NSFileManager *manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:filePath]){
        return [[manager attributesOfItemAtPath:filePath error:nil] fileSize] / (1024.0*1024);
    }
    return 0;
}


/**
 取视频第一帧
 */
+ (UIImage*)getVideoPreViewImage:(NSURL *)path
{
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:path options:nil];
    AVAssetImageGenerator *assetGen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    
    assetGen.appliesPreferredTrackTransform = YES;
    CMTime time = CMTimeMakeWithSeconds(0.0, 600);
    NSError *error = nil;
    CMTime actualTime;
    CGImageRef image = [assetGen copyCGImageAtTime:time actualTime:&actualTime error:&error];
    UIImage *videoImage = [[UIImage alloc] initWithCGImage:image];
    CGImageRelease(image);
    return videoImage;
}

@end
